package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.interfaces.AdminUserService;
import cn.huiyunche.base.service.mappers.SysAdminMenuMapper;
import cn.huiyunche.base.service.mappers.SysAdminMenuRoleMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.Result;
import cn.huiyunche.base.service.vo.SysAdminMenuBeanVo;
import cn.huiyunche.base.service.vo.SysAdminMenuVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 菜单控制器
 *
 * @author hdy [Tuffy]
 */
@Service
public class MenuServiceImpl {

    @Autowired
    private SysAdminMenuMapper sysAdminMenuMapper = null;

    @Autowired
    private AdminUserService adminUserService = null;

    @Autowired
    private RoleServiceImpl roleServiceImpl = null;

    @Autowired
    private SysAdminMenuRoleMapper sysAdminMenuRoleMapper = null;

    /**
     * 获取某个banner下的菜单
     *
     * @param bannerId bannerId
     * @return
     */
    public Result<List<SysAdminMenuVo>> bannerMenu(Long bannerId) {
        Result<List<SysAdminMenuVo>> r = new Result<>(true);
        // 菜单数据
        if (null == bannerId) {
            return r;
        }
        // 当前用户角色
        SysAdminRole sar = this.getRoleServiceImpl().getUserRole(this.getAdminUserService().getThisUser().getId());
        // 角色下菜单
        r.setData(this.menuList(bannerId, null, sar.getId()));
        return r;
    }

    /**
     * 根据主键查询菜单信息
     *
     * @param id
     * @return
     */
    public Result<SysAdminMenuVo> byId(Long id) {
        Result<SysAdminMenuVo> r = new Result<>(false);
        if (null == id) {
            r.setMessage("此记录不存在");
            return r;
        }
        SysAdminMenu sam = this.getSysAdminMenuMapper().selectByPrimaryKey(id);
        SysAdminMenuVo samv = new SysAdminMenuVo();
        SysAdminMenuBeanVo sambv = this.getMenuRoles(sam);
        BeanCopier beanCopierV = BeanCopier.create(SysAdminMenuBeanVo.class, SysAdminMenuVo.class, false);
        beanCopierV.copy(sambv, samv, null);
        samv.setList(this.getMenuByParentId(samv.getId()));
        r.setData(samv);
        r.setSuccess(true);
        return r;
    }

    /**
     * 获取某个banner下的菜单
     *
     * @return
     */
    public Result<List<SysAdminMenuVo>> allMenu() {
        Result<List<SysAdminMenuVo>> r = new Result<>(true);
        // 菜单数据
        r.setData(this.menuList(null, null, null));
        return r;
    }

    /**
     * 删除菜单
     *
     * @param id 主键
     * @return
     */
    public Result<String> removeMenu(Long id) {
        Result<String> r = new Result<>(false);
        if (null == id) {
            r.setMessage("记录不存在");
            return r;
        }
        // 删除子菜单
        SysAdminMenuExample same = new SysAdminMenuExample();
        same.createCriteria().andParentIdEqualTo(id);
        this.getSysAdminMenuMapper().deleteByExample(same);
        // 删除主菜单
        this.getSysAdminMenuMapper().deleteByPrimaryKey(id);
        r.setSuccess(true);
        return r;
    }

    /**
     * 编辑菜单
     *
     * @param sam
     * @return
     */
    public Result<String> saveMenu(SysAdminMenu sam, String roleIds) {
        Result<String> r = new Result<>(false);
        Long id = sam.getId();
        if (StringUtils.isBlank(sam.getTitle())) {
            r.setMessage("完善菜单标题");
            return r;
        }
        if (StringUtils.isBlank(roleIds)) {
            r.setMessage("请指定菜单角色");
            return r;
        }
        if (null == sam.getBannerId()) {
            r.setMessage("请指定banner");
            return r;
        }
        // 添加
        if (null == id) {
            this.getSysAdminMenuMapper().insertSelective(sam);
            this.insertMenuRole(sam.getId(), roleIds);
            r.setSuccess(true);
            return r;
        }
        // 修改
        SysAdminMenu samModify = this.getSysAdminMenuMapper().selectByPrimaryKey(id);
        if (null == samModify) {
            r.setMessage("此记录不存在");
            return r;
        }
        this.getSysAdminMenuMapper().updateByPrimaryKey(sam);
        // 检测中间表数据
        this.removeMenuRole(sam, roleIds);
        r.setSuccess(true);
        return r;
    }

    /**
     * 删除菜单角色
     *
     * @param roleIds
     */
    private void removeMenuRole(SysAdminMenu sam, String roleIds) {
        List<SysAdminRole> list = this.getRoleServiceImpl().getRolesByMenuId(sam.getId());
        StringBuffer sb = new StringBuffer("");
        for (SysAdminRole sar : list) {
            sb.append(sar.getId() + ",");
        }
        String roleStr = sb.toString();
        if (roleStr.length() > 0) {
            roleStr = roleStr.substring(0, roleStr.length() - 1);
        }
        // 校验数据
        if (!roleStr.equals(roleIds)) {
            // 删除原有中间数据
            for (SysAdminRole sar : list) {
                SysAdminMenuRoleExample example = new SysAdminMenuRoleExample();
                example.createCriteria().andRoleIdEqualTo(sar.getId()).andMenuIdEqualTo(sam.getId());
                this.getSysAdminMenuRoleMapper().deleteByExample(example);
            }
            // 添加新数据
            String[] roleIdArray = roleIds.split(",");
            for (String s : roleIdArray) {
                SysAdminMenuRole samr = new SysAdminMenuRole();
                samr.setMenuId(sam.getId());
                samr.setRoleId(NumberUtils.toLong(s));
                this.getSysAdminMenuRoleMapper().insert(samr);
            }
        }
    }

    /**
     * 添加菜单角色表
     *
     * @param menuId
     * @param roleIds
     */
    private void insertMenuRole(Long menuId, String roleIds) {
        String[] str = roleIds.split(",");
        for (String s : str) {
            SysAdminMenuRole samr = new SysAdminMenuRole();
            samr.setMenuId(menuId);
            samr.setRoleId(NumberUtils.toLong(s));
            this.getSysAdminMenuRoleMapper().insert(samr);
        }
    }

    /**
     * 获取一级菜单
     *
     * @param id
     * @return
     */
    public Result<List<SysAdminMenu>> getParentIdList(Long id) {
        Result<List<SysAdminMenu>> r = new Result<>(true);
        SysAdminMenuExample same = new SysAdminMenuExample();
        SysAdminMenuExample.Criteria c = same.createCriteria();
        c.andParentIdIsNull();
        if (null != id && id > 0) {
            c.andIdNotEqualTo(id);
        }
        r.setData(this.getSysAdminMenuMapper().selectByExample(same));
        return r;
    }

    /**
     * 获取菜单列表
     *
     * @return
     */
    private List<SysAdminMenuVo> menuList(Long bannerId, Long menuId, Long roleId) {
        List<SysAdminMenuVo> listVo = new ArrayList<>();
        SysAdminMenuExample same = new SysAdminMenuExample();
        SysAdminMenuExample.Criteria c = same.createCriteria();
        c.andParentIdIsNull();
        if (null != bannerId) {
            c.andBannerIdEqualTo(bannerId);
        }
        if (null != menuId) {
            c.andIdEqualTo(menuId);
        }
        same.setOrderByClause("sort ASC");
        List<SysAdminMenu> list = null;
        if (null == roleId) {
            list = this.getSysAdminMenuMapper().selectByExample(same);
        } else {
            list = this.getMenuByRoleId(roleId, bannerId);
        }
        for (SysAdminMenu sam : list) {
            SysAdminMenuBeanVo sambv = this.getMenuRoles(sam);
            SysAdminMenuVo samv = new SysAdminMenuVo();
            BeanCopier beanCopierV = BeanCopier.create(SysAdminMenuBeanVo.class, SysAdminMenuVo.class, false);
            beanCopierV.copy(sambv, samv, null);
            // 获取子菜单
            samv.setList(this.getMenuByParentId(samv.getId()));
            listVo.add(samv);
        }
        return listVo;
    }

    /**
     * 获取子菜单
     *
     * @param parentId
     * @return
     */
    private List<SysAdminMenu> getMenuByParentId(Long parentId) {
        SysAdminMenuExample same = new SysAdminMenuExample();
        same.createCriteria().andParentIdEqualTo(parentId);
        same.setOrderByClause("sort ASC");
        return this.getSysAdminMenuMapper().selectByExample(same);
    }

    /**
     * 根据角色id 获取菜单
     *
     * @param roleId
     * @return
     */
    private List<SysAdminMenu> getMenuByRoleId(Long roleId, Long bannerId) {
        SysAdminMenuRoleExample samre = new SysAdminMenuRoleExample();
        samre.createCriteria().andRoleIdEqualTo(roleId);
        List<SysAdminMenuRole> mrList = this.getSysAdminMenuRoleMapper().selectByExample(samre);
        List<Long> menuIds = new ArrayList<>();
        for (SysAdminMenuRole samr : mrList) {
            menuIds.add(samr.getMenuId());
        }
        if (menuIds.size() <= 0) {
            return new ArrayList<>();
        }
        SysAdminMenuExample same = new SysAdminMenuExample();
        same.setOrderByClause("sort ASC");
        same.createCriteria().andParentIdIsNull().andIdIn(menuIds).andBannerIdEqualTo(bannerId);
        return this.getSysAdminMenuMapper().selectByExample(same);
    }

    /**
     * 获取菜单角色列表
     *
     * @param sam
     * @return
     */
    private SysAdminMenuBeanVo getMenuRoles(SysAdminMenu sam) {
        SysAdminMenuBeanVo sambv = new SysAdminMenuBeanVo();
        BeanCopier beanCopierT = BeanCopier.create(SysAdminMenu.class, SysAdminMenuBeanVo.class, false);
        beanCopierT.copy(sam, sambv, null);
        List<SysAdminRole> roleList = this.getRoleServiceImpl().getRolesByMenuId(sambv.getId());
        sambv.setRoleList(roleList);
        sambv.setRoleIds(this.getRoleIds(roleList));
        sambv.setRoleNames(this.getRoleNames(roleList));
        return sambv;
    }

    /**
     * 角色id字符串
     *
     * @param roles
     * @return
     */
    private List<Long> getRoleIds(List<SysAdminRole> roles) {
        List<Long> l = new ArrayList<>();
        for (SysAdminRole sar : roles) {
            l.add(sar.getId());
        }
        return l;
    }

    /**
     * 角色name字符串
     *
     * @param roles
     * @return
     */
    private String getRoleNames(List<SysAdminRole> roles) {
        StringBuffer sb = new StringBuffer("");
        for (SysAdminRole sar : roles) {
            sb.append(sar.getName() + ",");
        }
        String roleNames = sb.toString();
        if (roleNames.length() > 0) {
            roleNames = roleNames.substring(0, roleNames.length() - 1);
        }
        return roleNames;
    }

    private SysAdminMenuMapper getSysAdminMenuMapper() {
        return this.sysAdminMenuMapper;
    }

    private AdminUserService getAdminUserService() {
        return this.adminUserService;
    }

    private RoleServiceImpl getRoleServiceImpl() {
        return this.roleServiceImpl;
    }

    private SysAdminMenuRoleMapper getSysAdminMenuRoleMapper() {
        return this.sysAdminMenuRoleMapper;
    }
}
